package cc.kzc.adminauth.exception;

import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import com.alibaba.fastjson2.JSON;

import cc.kzc.adminauth.common.BaseResponse;
import cc.kzc.adminauth.common.ErrorCode;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@ControllerAdvice
public class FailedResponseExceptionHandler {

	// MissingServletRequestPartException
	@ResponseBody
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(MissingServletRequestPartException.class)
	public String exceptionHandler(MissingServletRequestPartException e) {
		log.info("[MissingServletRequestPartException]{}", e.getMessage());
		return JSON.toJSONString(BaseResponse.fail(ErrorCode.CLI_PARAM_MISSING, e.getMessage()));
	}

	// MissingServletRequestParameterException
	// get参数上使用验证捕捉
	@ResponseBody
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(MissingServletRequestParameterException.class)
	public String exceptionHandler(MissingServletRequestParameterException e) {
		log.info("[MissingServletRequestParameterException]{}", e.getMessage());
		return JSON.toJSONString(BaseResponse.fail(ErrorCode.CLI_PARAM_MISSING, e.getMessage()));
	}

	// MethodArgumentTypeMismatchException
	@ResponseBody
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(MethodArgumentTypeMismatchException.class)
	public String exceptionHandler(MethodArgumentTypeMismatchException e) {
		log.info("[MethodArgumentTypeMismatchException]{}", e.getMessage());
		return JSON.toJSONString(BaseResponse.fail(ErrorCode.CLI_PARAM_VALUE_FORMAT_ERR, e.getMessage()));
	}

	// MultipartException
	@ResponseBody
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(MultipartException.class)
	public String exceptionHandler(MultipartException e) {
		log.info("[MultipartException]{}", e.getMessage());
		return JSON.toJSONString(BaseResponse.fail(ErrorCode.CLI_CONTENT_TYPE_ERR, e.getMessage()));
	}

	// get参数上使用验证捕捉
	@ResponseBody
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(ValidationException.class)
	public String exceptionHandler(ValidationException e) {
		String exceptionClassName = e.getClass().getSimpleName();
		if (e instanceof ConstraintViolationException) {
			exceptionClassName = ConstraintViolationException.class.getSimpleName();
		}

		log.info("[{}]{}", exceptionClassName, e.getMessage());
		return JSON.toJSONString(BaseResponse.fail(ErrorCode.CLI_PARAM_ERR, e.getMessage()));
	}

	// post实体类参数使用验证捕捉
	@ResponseBody
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(value = MethodArgumentNotValidException.class)
	public String exceptionHandler(MethodArgumentNotValidException e) {
		BindingResult bindingResult = e.getBindingResult();
		StringBuilder errorMesssage = new StringBuilder();
		for (FieldError fieldError : bindingResult.getFieldErrors()) {
			errorMesssage.append(fieldError.getDefaultMessage()).append("!");
		}
		log.info("[MethodArgumentNotValidException]{}", errorMesssage.toString());
		return JSON.toJSONString(BaseResponse.fail(ErrorCode.CLI_PARAM_ERR, errorMesssage.toString()));
	}

	// 自定义TodoError
	@ResponseBody
	@ResponseStatus(HttpStatus.OK)
	@ExceptionHandler(value = BaseError.class)
	public String exceptionHandler(BaseError e) {
		log.info("[BaseError]{}", e.getMessage());
		return JSON.toJSONString(e.toResponse());
	}

	// 自定义ForbiddenError
	@ResponseBody
	@ResponseStatus(HttpStatus.FORBIDDEN)
	@ExceptionHandler(value = ForbiddenError.class)
	public String exceptionHandler(ForbiddenError e) {
		log.info("[ForbiddenError]{}", e.getMessage());
		return JSON.toJSONString(e.toResponse());
	}

}
